package com.richpencil.utils;


import com.alibaba.fastjson.JSON;

import java.security.DigestException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;

public class WechatHelper {
/*
	public static RedPackObject getRedPackReturnCode(Map<String, String> map) {
		
		RedPackObject robject=new RedPackObject(map);
		return robject;
	}
	
	public static UnifiedOrderObject getRequestReturnCode( HttpServletRequest request) throws IOException
	{
		InputStream inStream = request.getInputStream();
		ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = 0;
		while ((len = inStream.read(buffer)) != -1) {
			outSteam.write(buffer, 0, len);
		}
		outSteam.close();
		inStream.close();
		String result = new String(outSteam.toByteArray(), "utf-8");// 获取微信调用我们notify_url的返回信息
		Map<String, Object> map = StringHelper.getXMLToMap(result);
		UnifiedOrderObject object=new UnifiedOrderObject(map);
		return object;
	}*/
	
	
	//付款成功，返回给微信服务器的消息
	public static String setWechatPayReturnXML(String return_code, String return_msg) {
		return "<xml><return_code><![CDATA[" + return_code
				+ "]]></return_code><return_msg><![CDATA[" + return_msg
				+ "]]></return_msg></xml>";
	}
	
	/**
     * 微信获取accesstoken
     * 
     * @param 	appid
     * @param 	secret
     * @return 	accesstoken
     */
    public static String wxGetAccessToken(String appid, String secret){
    	String jsonobject = HttpHelper.sendGet("https://api.weixin.qq.com/cgi-bin/token",
				"grant_type=client_credential&appid="+appid+"&secret="+secret);
		Map maps = (Map) JSON.parse(jsonobject);
        String accesstoken = maps.get("access_token").toString();
	  	return accesstoken;
    }
    
    
    
	//获取token
	public static final String URL_access_token = "https://api.weixin.qq.com/cgi-bin/token";
	//统一下单
	public static final String URL_unifiedorder = "https://api.mch.weixin.qq.com/pay/unifiedorder";
	//oauth2请求授权
	public static final String URL_oauth2 = "https://open.weixin.qq.com/connect/oauth2/authorize";
	//oauth2获取access_token
	public static final String URL_oauth2token = "https://api.weixin.qq.com/sns/oauth2/access_token";
	//根据token获取ticket
	public static final String URL_getticket = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";
	//拉取用户信息(需scope为 snsapi_userinfo)
	public static final String URL_userinfo = "https://api.weixin.qq.com/sns/userinfo";
	
	
	

	//微信开放平台审核通过的应用APPID
	public static final String appid = "wxce96b9dd56cd24e7";
	//应用密钥
	public static final String appsecret = "16d112c45a61b6a4c6719473ad436c22";
	//微信支付分配的商户号
	public static final String mch_id = "1484459972";
	//终端设备号(门店号或收银设备ID)，默认请传"WEB"
	public static final String device_info = "WEB";
	//支付类型
	public static final String trade_type = "JSAPI";
	//指定支付方式  no_credit--指定不能使用信用卡支付
	public static final String limit_pay = "limit_pay";
	// 字符编码格式 目前支持utf-8
    public static final String input_charset = "utf-8";
    /**
     * 弹出授权页面，可通过openid拿到昵称、性别、所在地。并且，即使在未关注的情况下，只要用户授权，也能获取其信息
     */
    public static final String scope_snsapi_userinfo = "snsapi_userinfo";
    /**
     * 不弹出授权页面，直接跳转，只能获取用户openid
     */
    public static final String scope_snsapi_base = "snsapi_base";
    
    private static Map<String, Object> accessTokenCache = new HashMap<String, Object>();
    private static Map<String, Object> jsapiTicketCache = new HashMap<String, Object>();
    public static String getAccessToken(){
    	String access_token = "";
    	String tokenKey = "tokenKey";
    	String tokenTimeKey = "tokenTimeKey";
    	String appId = appid;
    	String appSecret = appsecret;
    	SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
    	try{
    		if(accessTokenCache.containsKey(tokenKey)){
    			Date cacheTime = (Date)accessTokenCache.get(tokenTimeKey);//获取token时间
    			long currentTime = System.currentTimeMillis();//系统当前实际时间
    			long cacheCreateTime = cacheTime.getTime();//token创建时间
    			long diffTime = currentTime - cacheCreateTime;//token持续时间
    			int cacheMinutes = 5;//分钟
    			long cacheTimeRange = cacheMinutes * 60  * 1000;
    			if (diffTime < cacheTimeRange ){//token持续7分钟以内，使用原token
    				access_token = (String)accessTokenCache.get(tokenKey);
    			}
    		}
    		if(access_token.equals("")){
	    		Map map = new HashMap();
	    		map.put("grant_type", "client_credential");
	    		map.put("appid", appId);
	    		map.put("secret", appSecret);
	    		String str_Token = uHttps.sendPost(URL_access_token, map);
	    		Map map_Token = StringHelper.jsonStr2Map(str_Token);
	    		access_token = map_Token.get("access_token").toString();
	    		accessTokenCache.put(tokenKey, access_token);
	    		accessTokenCache.put(tokenTimeKey, new Date());
    		}
    	}
    	catch(Exception ex){
    		access_token = "";
    	}
		return access_token;
	} 
    public static String getJsapiTicket(){
    	String access_token = getAccessToken();
    	String jsapi_ticket = "";
    	String ticketKey = "ticketKey";
    	String ticketTimeKey = "ticketTimeKey";
    	SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
    	try{
    		if(jsapiTicketCache.containsKey(ticketKey)){
    			Date cacheTime = (Date)jsapiTicketCache.get(ticketTimeKey);//获取token时间
    			long currentTime = System.currentTimeMillis();//系统当前实际时间
    			long cacheCreateTime = cacheTime.getTime();//token创建时间
    			long diffTime = currentTime - cacheCreateTime;//token持续时间
    			int cacheMinutes = 5;//分钟
    			long cacheTimeRange = cacheMinutes * 60  * 1000;
    			if (diffTime < cacheTimeRange ){//token持续7分钟以内，使用原token
    				jsapi_ticket = jsapiTicketCache.get(ticketKey).toString();
    			}
    		}
    		if(jsapi_ticket.equals("")){
	    		Map<String, String> map = new HashMap<>();
	    		map.put("access_token", access_token);
	    		map.put("type", "jsapi");
	    		String str_Token = uHttps.sendPost(URL_getticket, map);
	    		Map map_Ticket = StringHelper.jsonStr2Map(str_Token);
	    		jsapi_ticket = map_Ticket.get("ticket").toString();
	    		jsapiTicketCache.put(ticketKey, jsapi_ticket);
	    		jsapiTicketCache.put(ticketTimeKey, new Date());
    		}
    	}
    	catch(Exception ex){
    		jsapi_ticket = "";
    	}
		return jsapi_ticket;
	}
    
	/** 
	 * SHA1 安全加密算法 
	 * @param maps 参数key-value map集合 
	 * @return 
	 * @throws DigestException
	 */  
	public static String SHA1(Map<String, Object> maps) throws DigestException {
		//获取信息摘要 - 参数字典排序后字符串  
		String decrypt = getOrderByLexicographic(maps);
		try {  
			//指定sha1算法  
			MessageDigest digest = MessageDigest.getInstance("SHA-1");
			digest.update(decrypt.getBytes());  
			//获取字节数组  
			byte messageDigest[] = digest.digest();  
			// Create Hex String  
			StringBuffer hexString = new StringBuffer();
			// 字节数组转换为 十六进制 数  
			for (int i = 0; i < messageDigest.length; i++) {  
				String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
				if (shaHex.length() < 2) {  
					hexString.append(0);  
				}  
				hexString.append(shaHex);  
			}  
			return hexString.toString().toUpperCase();  
  
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();  
			throw new DigestException("签名错误！");
		}  
    }
	/**
	 * 获取参数的字典排序 
	 * @param maps 参数key-value map集合 
	 * @return String 排序后的字符串 
	 */
	private static String getOrderByLexicographic(Map<String, Object> maps){
		System.out.println(splitParams(lexicographicOrder(getParamsName(maps)),maps));
		//jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW&timestamp=1414587457&url=http://mp.weixin.qq.com?params=value
		//jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW&timestamp=1414587457&url=http://mp.weixin.qq.com?params=value
        return splitParams(lexicographicOrder(getParamsName(maps)),maps);  
    }
	/** 
	 * 获取参数名称 key 
	 * @param maps 参数key-value map集合 
	 * @return 
	*/  
    private static List<String> getParamsName(Map<String, Object> maps){
        List<String> paramNames = new ArrayList<String>();
        for(Map.Entry<String, Object> entry : maps.entrySet()){
            paramNames.add(entry.getKey());  
        }  
        return paramNames;  
    }
	/** 
	 * 参数名称按字典排序 
	 * @param paramNames 参数名称List集合 
	 * @return 排序后的参数名称List集合 
	 */  
	private static List<String> lexicographicOrder(List<String> paramNames){
		Collections.sort(paramNames);
		return paramNames;  
	}
	/** 
	 * 拼接排序好的参数名称和参数值 
	 * @param paramNames 排序后的参数名称集合 
	 * @param maps 参数key-value map集合 
	 * @return String 拼接后的字符串 
	 */  
	private static String splitParams(List<String> paramNames, Map<String, Object> maps){
		StringBuilder paramStr = new StringBuilder();
		for(String paramName : paramNames){
			paramStr.append(paramName);  
			for(Map.Entry<String, Object> entry : maps.entrySet()){
				if(paramName.equals(entry.getKey())){  
					paramStr.append("="+ String.valueOf(entry.getValue())+"&");
				}  
			}  
		}  
		paramStr.deleteCharAt(paramStr.length()-1);
		return paramStr.toString();  
	}    
}
